<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

/** load the CI class for Modular Extensions **/
require dirname(__FILE__).'/Base.php';
class Controller 
{
	public $autoload = array();
	public $template='default';
	private static $instance;
	public $_ci_models= array();
	protected $_ci_cached_vars		= array();
	public $buffer;
	
	public function __construct() 
	{
		$class = str_replace(CI::$APP->config->item('controller_suffix'), '', get_class($this));
		log_message('debug', $class." controller Initialized");
		Modules::$registry[strtolower($class)] = $this;	
		
		/* copy a loader instance and initialize */
		$this->load = clone load_class('Loader');
		$this->load->initialize($this);	
		
		/* autoload module items */
		$this->load->_autoloader($this->autoload);
	}
	
	public function __get($class) {
		if(isset(CI::$APP->$class))
			return CI::$APP->$class;
		return false;
	}
	public static function get_instance()
	{
		return self::$instance;
	}
	
	private function loadViewFile($directory,$_ci_view){
		//find file in views, in template, in template/directory
		$_ci_paths=array(FCPATH."application/modules/$directory/views/$_ci_view.php",
						FCPATH."template/{$this->template}/$_ci_view.php",
						FCPATH."template/{$this->template}/$directory/$_ci_view.php");
		foreach ($_ci_paths as $path)
			if (file_exists($path))
				return $path;
		show_error('Unable to load the requested view file or templete file: '.$_ci_view);
	}
	public function view($_ci_view='', $_ci_vars=array(),$_ci_return= FALSE)
	{
		$CI = get_instance();
		
		$object = new ReflectionObject($this);
		$get_name=str_replace('\\','/',$object->getFileName());
		$extract=explode('/application/modules/',$get_name);
		$directory_class= explode('/controllers/',$extract[1]);
		$directory=$directory_class[0];
		$class=str_replace('.php', '', $directory_class[1]);

		if(empty($this->template)) {
			if(isset($CI->template)) $this->template=$CI->template;
		}
		if(!is_array($_ci_view)){
			if($_ci_view==''){
				$temp=explode('_',get_class($this));
				$_ci_view= array_pop($temp);
			}
			$_ci_path=self::loadViewFile($directory,$_ci_view);
		}else{
			foreach ($_ci_view as $view)
				$_ci_path[]=self::loadViewFile($directory,$view);
		}
	
		// This allows anything loaded using $this->load (views, files, etc.)
		// to become accessible from within the Controller and Model functions.
		foreach (get_object_vars($CI) as $_ci_key => $_ci_var)
			if ( ! isset($this->$_ci_key))
				$this->$_ci_key =$CI->$_ci_key;
		/*
		 * Extract and cache variables
		*
		* You can either set variables using the dedicated $this->load_vars()
		* function or via the second parameter of this function. We'll merge
		* the two types and cache them so that views that are embedded within
		* other views can have access to these variables.
		*/
		if (is_array($_ci_vars))
			$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
		extract($this->_ci_cached_vars);
		/*
		 * Buffer the output
		*
		* We buffer the output for two reasons:
		* 1. Speed. You get a significant speed boost.
		* 2. So that the final rendered template can be
		* post-processed by the output class.  Why do we
		* need post processing?  For one thing, in order to
		* show the elapsed page load time.  Unless we
		* can intercept the content right before it's sent to
		* the browser and then stop the timer it won't be accurate.
		*/
		ob_start();
	
		// If the PHP installation does not support short tags we'll
		// do a little string replacement, changing the short tags
		// to standard PHP echo statements.
		
		if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
		{
			if(!is_array($_ci_path)){
				eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
			}else {
				foreach ($_ci_path as $path)
					if (!file_exists($path))
						eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($path))));
			}
			
		}
		else{
			if(!is_array($_ci_path)){
				include($_ci_path); // include() vs include_once() allows for multiple views with the same name
			}else {
				foreach ($_ci_path as $path)
					if (file_exists($path)){
						include($path);
					} // include() vs include_once() allows for multiple views with the same name
			}
		}
	
		//log_message('debug', 'File loaded: '.$path);
	
		// Return the file data if requested
		if ($_ci_return === TRUE)
		{
			$this->buffer = ob_get_contents();
			@ob_end_clean();
			return $this;
		}
	
		/*
		 * Flush the buffer... or buff the flusher?
		*
		* In order to permit views to be nested within
		* other views, we need to flush the content back out whenever
		* we are beyond the first level of output buffering so that
		* it can be seen and included properly by the first included
		* template and any subsequent ones. Oy!
		*
		*/
		if (ob_get_level() > $this->_ci_ob_level + 1)
		{
			ob_end_flush();
		}
		else
		{
			$_ci_CI->output->append_output(ob_get_contents());
			@ob_end_clean();
		}
	}

	public function model($model='', $name = '', $db_conn = FALSE)
	{
		if (is_array($model)){
			foreach ($model as $babe)
			if(!empty($babe))$this->model($babe);
			return $this;
		}
		$path = '';
		if ($model == ''){
			$object = new ReflectionObject($this);
			$get_name=str_replace('\\','/',$object->getFileName());
			$extract=explode('/application/modules/',$get_name);
			
			$model= str_replace(array('/controllers/','.php'), array('_models_',''),$extract[1]);
		}
		// Is the model in a sub-folder? If so, parse out the filename and path.
		if (($last_slash = strrpos($model, '/')) !== FALSE)
		{
			// The path is in front of the last slash
			$path = substr($model, 0, $last_slash + 1).'/';
	
			// And the model name behind it
			$model = substr($model, $last_slash + 1);
		}
	
		if ($name == '') $name = $model;
	
		if (in_array($name, $this->_ci_models, TRUE)) return $this->$name;
	
		$model_path=str_replace('_', '/', $model);
		$models_path=APPPATH."modules/$path{$model_path}.php";
		
		$CI =& get_instance();
		if (isset($CI->$name))
		{
			return $CI->$name;
			//show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
		}
		if ( file_exists($models_path))
		{
	
			if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
			{
				if ($db_conn === TRUE)
				{
					$db_conn = '';
				}
				$CI->load->database($db_conn, FALSE, TRUE);
			}
			if ( ! class_exists('CI_Model'))
			{
				load_class('Model', 'core');
			}
			require_once($models_path);
			//$model = ucfirst($model)."Models";
			$CI->$name =new $name;
			//to do will add message error if wrong class's name
			$this->_ci_models[] = $name;
			
			return $CI->$name;
		}
	
		// couldn't find the model
		show_error('Unable to locate the model you have specified: '.$name);
	}
}